<?php

/**
 * File with Apk_Db_Table class
 *
 * @author Andrey Kucherenko
 */

/**
 * Abstract class for realization ORM concept, extend Zend_Db_Table,
 * keep method for pager generation and manipulation with data
 *
 */
abstract class Apk_Db_Table extends Zend_Db_Table {

    /**
     * Lines of dataset
     *
     * @var integer
     */
    protected $_count_line;

    /**
     * Current page
     *
     * @var integer
     */
    protected $_current_page;

    /**
     * Pager elements on page
     *
     * @var integer
     */
    protected $_pages_per_page;

    /**
     * Start item
     *
     * @var integer
     */
    protected $_start_item;

    /**
     * End item on page
     *
     * @var integer
     */
    protected $_end_item;

    /**
     * Class name for rowset objects
     *
     * @var string
     */
    protected $_rowsetClass = "Apk_Db_Table_Rowset";

    /**
     * Classname for row
     *
     * @var string
     */
    protected $_rowClass = 'Apk_Db_Table_Row';

    /**
     * Pager flag
     *
     * @var boolean
     */
    protected $_is_pager = false;
    protected $_cache_name = null;
    protected $_cache;

    /**
     * Decorator method name
     *
     * @var unknown_type
     */
    protected $_decorator = null;
    protected $_locale = 'ru_RU';

    /**
     * Set decorator method name
     *
     * @param string $name
     */
    public function setDecorator($name) {
        $this->_decorator = $name;

        return $this;
    }

    /**
     * Get decorator method name
     *
     * @return string
     */
    public function getDecorator() {
        $decorator = $this->_decorator;
        return $decorator;
    }

    /**
     * Clean decoratror method
     *
     */
    public function cleanDecorator() {
        $this->_decorator = null;
    }

    /**
     * Set data for paging
     *
     * @param integer $current_page
     * @param integer $count_line
     * @param integer $pages_per_page
     * @return Apk_Db_Table
     */
    public function pager($current_page, $count_line, $pages_per_page) {
        $this->_is_pager = true;
        $this->_current_page = intval($current_page);
        if ($this->_current_page < 1) {
            $this->_current_page = 1;
            $current_page = 1;
        }
        $this->_count_line = intval($count_line);
        $this->_pages_per_page = intval($pages_per_page);
        $this->_start_item = $count_line * ($current_page - 1);
        $this->_end_item = $count_line * $current_page;

        return $this;
    }

    /**
     * Set cache name
     *
     * @param string $cache_name
     * @return Apk_Db_Table
     */
    public function cache($cache_name, $cache_time = 60) {
        $this->_cache_name = $cache_name;


        $frontendOptions = array(
            'lifetime' => $cache_time,
            'automatic_serialization' => true
        );

        $type = @Zend_Registry::get('config')->cache->type;

        switch ($type) {
            case 'File':
                $backendOptions = array(
                    //'cacheDir' =>  Zend_Registry::get('config')->cache->path
                    'cache_dir' => Zend_Registry::get('catch_dir')
                );
                break;
            case 'Memcached':
                $backendOptions = array(
                    'servers' => Zend_Registry::get('config')->cache->servers->toArray()
                );
                break;

            default:
                $this->_cache = null;
                $this->_cache_name = null;
                return $this;
        }


        $this->_cache = Zend_Cache::factory('Core', $type, $frontendOptions, $backendOptions);

        return $this;
    }

    public function cache_off() {
        $this->_cache = null;
        $this->_cache_name = null;
    }

    /**
     * Create and execute query for get rows count in database
     *
     * @param select|string|Zend_Db_table_Select $where
     * @return integer
     */
    public function getCount($where = null) {
        if ($where instanceof Zend_Db_Table_Select) {
            $select = clone $where;
            $select->reset(Zend_Db_Select::FROM);
            $select->reset(Zend_Db_Select::COLUMNS);
            $select->from($this->_name, new Zend_Db_Expr('count(*)'));

            return $this->_db->fetchOne($select);
            /* $select->reset(Zend_Db_Select::FROM);
              $select->reset(Zend_Db_Select::COLUMNS);

              $select->from($this->_name, new Zend_Db_Expr('SQL_CALC_FOUND_ROWS id'));

              $this->_db->query($select);

              $res = $this->_db->fetchOne('SELECT FOUND_ROWS() as rowcount');
              return $res; */
        } else {
            $select = $this->_db->select();
            $select->from($this->_name, array('count_elem' => new Zend_Db_Expr('count(*)')));
            $where = (array) $where;
            foreach ($where as $key => $val) {
                // is $key an int?
                if (is_int($key)) {
                    // $val is the full condition
                    $select->where($val);
                } else {
                    // $key is the condition with placeholder,
                    // and $val is quoted into the condition
                    $select->where($key, $val);
                }
            }
            $stmt = $this->_db->query($select);

            $count = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
            return intval($count[0]['count_elem']);
        }
    }

    /**
     * Fetches all rows.
     *
     * Honors the Zend_Db_Adapter fetch mode.
     *
     * @param string|array|Zend_Db_Table_Select $select            OPTIONAL An SQL WHERE clause.
     * @param string|array  $order            OPTIONAL An SQL ORDER clause.
     * @param int           $count            OPTIONAL An SQL LIMIT count.
     * @param int           $offset           OPTIONAL An SQL LIMIT offset.
     * @return Gnews_Rowset The row results per the Zend_Db_Adapter fetch mode.
     */
    public function fetchAll($select = null, $order = null, $count = null, $offset = null) {

        if (is_null($this->_cache_name)) {
            $result = false;
        } else {
            $result = $this->_cache->load($this->_cache_name);
        }

        if (empty($result)) {
            $result = array();
            if ($this->_is_pager) {
                $count_lines = $this->getCount($select);
                if ($this->_current_page > $count_lines) {
                    $this->_current_page = $count_lines;
                    $this->_start_item = $this->_count_line * ($this->_current_page - 1);
                    $this->_end_item = $this->_count_line * $this->_current_page;
                }
                if ($this->_end_item > $count_lines) {
                    $this->_end_item = $count_lines;
                }


                $result = array();
                $result['items_on_page'] = $this->_count_line;
                $result['items_count'] = $count_lines;
                $pageCount = floor((($count_lines - 1) / $this->_count_line)) + 1;

                $result['page_count'] = $pageCount;

                $result['current_page'] = $this->_current_page;

                $result['start_item'] = $this->_start_item;

                $result['end_item'] = $this->_end_item;

                $result['first_page'] = 1;

                $result['previous_page'] = $this->_current_page - ($this->_current_page == 1 ? 0 : 1);
                if ($result['previous_page'] < 1) {
                    $result['previous_page'] = 1;
                }

                $result['next_page'] = $this->_current_page + ($this->_current_page == $pageCount ? 0 : 1);

                $result['last_page'] = $pageCount;

                $page_diff = floor($this->_pages_per_page / 2);

                $delta_start = 0;

                $delta_end = 0;

                if ($this->_current_page - $page_diff < 1) {
                    $result['start_page'] = 1;
                    $delta_start = $page_diff - $this->_current_page + 1;
                }
                if ($this->_current_page + $page_diff > $pageCount) {
                    $result['end_page'] = $pageCount;
                    $delta_end = ($this->_current_page + $page_diff) - $pageCount;
                }


                if ($this->_current_page - $page_diff >= 1) {
                    $result['start_page'] = $this->_current_page - $page_diff - $delta_end;
                    if ($result['start_page'] < 1) {
                        $result['start_page'] = 1;
                    }
                }

                if ($this->_current_page + $page_diff <= $pageCount) {
                    $result['end_page'] = $this->_current_page + $page_diff + $delta_start;
                    if ($result['end_page'] > $pageCount) {
                        $result['end_page'] = $pageCount;
                        $result['next_page'] = $pageCount;
                    }
                }


                $this->_is_pager = false;
                $count = $this->_count_line;
                if ($this->_start_item < 0) {
                    $this->_start_item = 0;
                    $result['start_item'] = 0;
                }
                $offset = $this->_start_item;
            }

            if (is_array($select) or is_string($select)) {
                $select = $this->select()->where($select);
            } elseif (is_null($select)) {
                $select = $this->select();
            }



            $select->order($order)->limit($count, $offset);



            $data = array(
                'table' => $this,
                'pager' => $result,
                'data' => $this->_fetch($select),
                'rowClass' => $this->_rowClass,
                'stored' => true
            );



            $result = new $this->_rowsetClass($data);

            if (!is_null($this->_cache_name)) {
                $this->_cache->save($result, $this->_cache_name);
            }
        }
        $this->cache_off();
        return $result;
    }

    /**
     * Get Data list from database via select.
     *
     * Honors the Zend_Db_Adapter fetch mode.
     *
     * @param Zend_Db_Select $select            OPTIONAL An SQL WHERE clause.
     * @return Zend_Db_Table_Rowset_Abstract The row results per the Zend_Db_Adapter fetch mode.
     */
    public function getList($select) {

        if (is_null($this->_cache_name)) {
            $result = false;
        } else {
            $result = $this->_cache->load($this->_cache_name);
        }

        if (empty($result)) {

            $stmt = $this->_db->query($select);

            $res = array();
            if (!is_null($this->_decorator)) {
                $decor = $this->_decorator;
                while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
                    $item = array();
                    foreach ($row as $key => $value) {
                        list($k, $v) = @each($this->$decor(strtolower($key), $value));
                        $item[strtolower($k)] = $v;
                    }
                    $res[] = $item;
                }
            } else {
                $res = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
            }

            foreach ($res as $k => $v)
                $res[$k] = array_change_key_case($res[$k], CASE_LOWER);

            //rint_r($res); die();

            $data = array(
                'table' => $this,
                'data' => $res,
                'rowClass' => $this->_rowClass,
                'stored' => true
            );

            $result = new $this->_rowsetClass($data);

            if (!is_null($this->_cache_name)) {
                $this->_cache->save($result, $this->_cache_name);
            }
        }
        $this->cache_off();


        return $result;
    }

    /**
     * Method for convert timestamp to array, for used at decorators
     *
     * @param integer $time
     * @return array
     *
     */
    protected function timestampToArray($time, $lang = 'ru') {
        $this->setLocal($lang);
        return Apk_Util::timestampToArray($time, $this->_locale);
    }

    protected function setLocal($lang = 'ru') {
        switch ($lang) {
            case 'ru':
                $this->_locale = 'ru_RU';
                break;
            case 'ua':
                $this->_locale = 'uk_UA';
                break;
            case 'en':
                $this->_locale = 'en_US';
                break;
            default:
                $this->_locale = 'ru_RU';
        }
    }

    /**
     * Support method for fetching rows.
     *
     * @param  string|array $where  OPTIONAL An SQL WHERE clause.
     * @param  string|array $order  OPTIONAL An SQL ORDER clause.
     * @param  int          $count  OPTIONAL An SQL LIMIT count.
     * @param  int          $offset OPTIONAL An SQL LIMIT offset.
     * @return array The row results, in FETCH_ASSOC mode.
     */
    protected function _fetch(Zend_Db_Table_Select $select) {

        //        if (!($where instanceof Zend_Db_Table_Select)) {
        //            $select = $this->select();
        //            if ($where !== null) {
        //                $this->_where($select, $where);
        //            }
        //        }else{
        //            $select = clone $where;
        //        }
        //        if (!is_array($order)) {
        //            $order = array($order);
        //        }
        //        foreach ($order as $val) {
        //            $select->order($val);
        //        }
        // the LIMIT clause
        //$select->limit($count, $offset);
        // selection tool
        /* $select = $this->_db->select();

          // the FROM clause
          $select->from($this->_name, $this->_cols, $this->_schema);

          // the WHERE clause
          $where = (array) $where;
          foreach ($where as $key => $val) {
          // is $key an int?
          if (is_int($key)) {
          // $val is the full condition
          $select->where($val);
          } else {
          // $key is the condition with placeholder,
          // and $val is quoted into the condition
          $select->where($key, $val);
          }
          }

          // the ORDER clause
          if (!is_array($order)) {
          $order = array($order);
          }
          foreach ($order as $val) {
          $select->order($val);
          }

          // the LIMIT clause
          $select->limit($count, $offset);
         */
        // return the results


        $stmt = $this->_db->query($select);

        $res = array();

        if (!is_null($this->_decorator)) {
            $decor = $this->_decorator;
            while ($row = $stmt->fetch(Zend_Db::FETCH_ASSOC)) {
                $item = array();
                foreach ($row as $key => $value) {
                    $decorating_row = $this->$decor($key, $value);
                    list($k, $v) = each($decorating_row);
                    $item[$k] = $v;
                }
                $res[] = $item;
            }
        } else {
            $res = $stmt->fetchAll(Zend_Db::FETCH_ASSOC);
        }
        $this->cache_off();
        $this->cleanDecorator();
        return $res;
    }

    // page - int : value for current page;
    // options['view_pages'] - int : count of showed pages
    public function getPagerAdvanced(Zend_Db_Select $select, $page = 1, array $options = array()) {
        $pre_select = clone( $select );

        $id = isset($options['id']) ? ($db instanceof Zend_Db_Adapter_Abstract ? $db->quoteIdentifier($id) : $id) : '*';

        //$pre_select->reset( Zend_Db_Select::COLUMNS );
        //$pre_select->from(null, array('count'=>new Zend_Db_Expr( 'count('.$id.')')) );
        //$count_element =  $pre_select->query()->fetchColumn();

        $sel = $this->getAdapter()->select()->from($select, array('count' => new Zend_Db_Expr('count(' . $id . ')')));
        $count_element = $sel->query()->fetchColumn();

        //echo $sel; die();


        $pager_options = array(
            'totalItems' => $count_element,
            'perPage' => isset($options['perPage']) ? $options['perPage'] : 10,
            'append' => true,
            'currentPage' => isset($page) ? $page : 1,
            'reverse' => false
        );

        $pager_options = array_merge($pager_options, $options);

        require_once 'Pager/Sliding.php';

        $pager = new Pager_Sliding($pager_options);

        list($from, ) = $pager->getOffsetByPageId();

        if ($pager_options['reverse']) {
            $from = $count_element - $from - $pager_options['perPage'];
            if ($from < 0)
                $from = 0;
        }

        $pre_select->limit($pager_options['perPage'], $from - 1);

        $view_pages = isset($options['view_pages']) ? $options['view_pages'] : 5;
        $radius_pages = isset($options['radius_pages']) ? $options['radius_pages'] : 2;

        $start_page = ($pager_options['currentPage'] - $radius_pages) > 0 ? ($pager_options['currentPage'] - $radius_pages) : 1;
        $end_page = ($pager_options['currentPage'] + $radius_pages) > $view_pages ? ($pager_options['currentPage'] + $radius_pages) : $view_pages;
        if ($end_page > $pager->numPages())
            $end_page = $pager->numPages();

        //echo $from;die();

        $ret['pager'] = array(
            'items_on_page' => $pager_options['perPage'],
            'items_count' => $pager_options['totalItems'],
            'page_count' => $pager->numPages(),
            'current_page' => $pager_options['currentPage'],
            'first_page' => 1,
            'last_page' => $pager->numPages(),
            'start_item' => $from,
            'end_item' => ($from + $pager_options['perPage'] - 1) > $pager_options['totalItems'] ? $pager_options['totalItems'] : ($from + $pager_options['perPage'] - 1),
            'previous_page' => $pager->getPreviousPageID(),
            'next_page' => $pager->getNextPageID(),
            'start_page' => $start_page,
            'end_page' => $end_page
        );

        $ret['data'] = $pre_select->query()->fetchAll(Zend_Db::FETCH_ASSOC);

        foreach ($ret['data'] as $k => $v)
            $ret['data'][$k] = array_change_key_case($v, CASE_LOWER);

        if (!is_null($this->_decorator)) {
            $decor = $this->_decorator;

            foreach ($ret['data'] as $idx => $row) {
                $item = array();
                foreach ($row as $key => $value) {
                    $decorating_row = $this->$decor($key, $value);
                    list($k, $v) = each($decorating_row);
                    $item[$k] = $v;
                }
                $ret['data'][$idx] = $item;
            }
        }

        return $ret;
    }

    // page - int : value for current page;
    // options['view_pages'] - int : count of showed pages
    public function getPager(Zend_Db_Select $select, $page = 1, array $options = array()) {
        $pre_select = clone( $select );

        $id = isset($options['id']) ? ($db instanceof Zend_Db_Adapter_Abstract ? $db->quoteIdentifier($id) : $id) : '*';

        $pre_select->reset(Zend_Db_Select::COLUMNS);
        $pre_select->from(null, array('count' => new Zend_Db_Expr('count(' . $id . ')')));

        $count_element = $pre_select->query()->fetchColumn();

        $pager_options = array(
            'totalItems' => $count_element,
            'perPage' => isset($options['perPage']) ? $options['perPage'] : 10,
            'append' => true,
            'currentPage' => isset($page) ? $page : 1,
            'reverse' => false
        );

        $pager_options = array_merge($pager_options, $options);

        require_once 'Pager/Sliding.php';

        $pager = new Pager_Sliding($pager_options);

        list($from, ) = $pager->getOffsetByPageId();

        if ($pager_options['reverse']) {
            $from = $count_element - $from - $pager_options['perPage'];
            if ($from < 0)
                $from = 0;
        }

        $select->limit($pager_options['perPage'], $from - 1);

        $view_pages = isset($options['view_pages']) ? $options['view_pages'] : 3; //10;
        $radius_pages = isset($options['radius_pages']) ? $options['radius_pages'] : 1; //5;//2;

        $start_page = ($pager_options['currentPage'] - $radius_pages) > 0 ? ($pager_options['currentPage'] - $radius_pages) : 1;
        $end_page = ($pager_options['currentPage'] + $radius_pages) > $view_pages ? ($pager_options['currentPage'] + $radius_pages) : $view_pages;
        if ($end_page > $pager->numPages())
            $end_page = $pager->numPages();

        //echo $from;die();

        $ret['pager'] = array(
            'items_on_page' => $pager_options['perPage'],
            'items_count' => $pager_options['totalItems'],
            'page_count' => $pager->numPages(),
            'current_page' => $pager_options['currentPage'],
            'first_page' => 1,
            'last_page' => $pager->numPages(),
            'start_item' => $from,
            'end_item' => ($from + $pager_options['perPage'] - 1) > $pager_options['totalItems'] ? $pager_options['totalItems'] : ($from + $pager_options['perPage'] - 1),
            'previous_page' => $pager->getPreviousPageID(),
            'next_page' => $pager->getNextPageID(),
            'start_page' => $start_page,
            'end_page' => $end_page
        );

		//echo $select; die();
        $ret['data'] = $select->query()->fetchAll(Zend_Db::FETCH_ASSOC);
        foreach ($ret['data'] as $k => $v)
            $ret['data'][$k] = array_change_key_case($v, CASE_LOWER);

        if (!is_null($this->_decorator)) {
            $decor = $this->_decorator;

            foreach ($ret['data'] as $idx => $row) {
                $item = array();
                foreach ($row as $key => $value) {
                    $decorating_row = $this->$decor($key, $value);
                    list($k, $v) = each($decorating_row);
                    $item[$k] = $v;
                }
                $ret['data'][$idx] = $item;
            }
        }

        return $ret;
    }


     // page - int : value for current page;
    // options['view_pages'] - int : count of showed pages
    public function getPagerMssql(Zend_Db_Select $select, $page = 1, array $options = array()) {
        $pre_select = clone( $select );

        $id = isset($options['id']) ? ($db instanceof Zend_Db_Adapter_Abstract ? $db->quoteIdentifier($id) : $id) : '*';

        $pre_select->reset(Zend_Db_Select::COLUMNS);
        $pre_select->from(null, array('count' => new Zend_Db_Expr('count(' . $id . ')')));

        $count_element = $pre_select->query()->fetchColumn();

        $pager_options = array(
            'totalItems' => $count_element,
            'perPage' => isset($options['perPage']) ? $options['perPage'] : 10,
            'append' => true,
            'currentPage' => isset($page) ? $page : 1,
            'reverse' => false
        );

        $pager_options = array_merge($pager_options, $options);

        require_once 'Pager/Sliding.php';

        $pager = new Pager_Sliding($pager_options);

        list($from, ) = $pager->getOffsetByPageId();

        if ($pager_options['reverse']) {
            $from = $count_element - $from - $pager_options['perPage'];
            if ($from < 0)
                $from = 0;
        }

        $select->columns('row_number() over (order by sf_file_name) r');
        $select = $this->getAdapter()->select()
        			->from($select)->where('r between '.($from - 1).' and '.($pager_options['perPage'] + ($from - 1)));

        //$select->limit($pager_options['perPage'], $from - 1);

        $view_pages = isset($options['view_pages']) ? $options['view_pages'] : 3; //10;
        $radius_pages = isset($options['radius_pages']) ? $options['radius_pages'] : 1; //5;//2;

        $start_page = ($pager_options['currentPage'] - $radius_pages) > 0 ? ($pager_options['currentPage'] - $radius_pages) : 1;
        $end_page = ($pager_options['currentPage'] + $radius_pages) > $view_pages ? ($pager_options['currentPage'] + $radius_pages) : $view_pages;
        if ($end_page > $pager->numPages())
            $end_page = $pager->numPages();

        //echo $from;die();

        $ret['pager'] = array(
            'items_on_page' => $pager_options['perPage'],
            'items_count' => $pager_options['totalItems'],
            'page_count' => $pager->numPages(),
            'current_page' => $pager_options['currentPage'],
            'first_page' => 1,
            'last_page' => $pager->numPages(),
            'start_item' => $from,
            'end_item' => ($from + $pager_options['perPage'] - 1) > $pager_options['totalItems'] ? $pager_options['totalItems'] : ($from + $pager_options['perPage'] - 1),
            'previous_page' => $pager->getPreviousPageID(),
            'next_page' => $pager->getNextPageID(),
            'start_page' => $start_page,
            'end_page' => $end_page
        );

		//echo $select; die();
        $ret['data'] = $select->query()->fetchAll(Zend_Db::FETCH_ASSOC);
        foreach ($ret['data'] as $k => $v)
            $ret['data'][$k] = array_change_key_case($v, CASE_LOWER);

        if (!is_null($this->_decorator)) {
            $decor = $this->_decorator;

            foreach ($ret['data'] as $idx => $row) {
                $item = array();
                foreach ($row as $key => $value) {
                    $decorating_row = $this->$decor($key, $value);
                    list($k, $v) = each($decorating_row);
                    $item[$k] = $v;
                }
                $ret['data'][$idx] = $item;
            }
        }

        return $ret;
    }

    // order with UP/DOWN pointer
    public function OrderDirect($id, $d, $params = array()) {
        $sel = $this->getAdapter()->select()
                ->from($this->_name)
                ->where('is_ghost = 0')
                ->where('is_removed = 0')
                ->order('norder');

        if (count($params) > 0)
            foreach ($params as $k => $v) {
                switch ($k) {
                    default:
                        if (intval($v) > 0)
                            $sel->where($this->_name . '.' . $k . ' = ?', $v);
                }
            }

        $data = $this->getList($sel)->toArray();


        foreach ($data as $k => $v) {

            if ($v['id'] == $id) {
                if ($d == 1 && $k > 0) {
                    parent::update(array('norder' => $k), 'id = ' . $v['id']);
                    parent::update(array('norder' => $k + 1), 'id = ' . $data[$k - 1]['id']);
                    break;
                }

                if ($d == 2 && $k < count($data) - 1) {
                    parent::update(array('norder' => $k + 2), 'id = ' . $v['id']);
                    parent::update(array('norder' => $k + 1), 'id = ' . $data[$k + 1]['id']);
                    break;
                }
            }

            parent::update(array('norder' => $k + 1), 'id = ' . $v['id']);
        }
    }

    // order with set norder value
    public function OrderNumber($id, $norder, $old_order, $params = array()) {
        $sel = $this->getAdapter()->select()
                ->from($this->_name)
                ->where('is_ghost = 0')
                ->where('is_removed = 0')
                ->order('norder');

        if (count($params) > 0)
            foreach ($params as $k => $v)
                switch ($k) {
                    default:
                        if (intval($v) > 0)
                            $sel->where($this->_name . '.' . $k . ' = ?', $v);
                }

        $data = $this->getList($sel)->toArray();

        if ($norder <= 0)
            $norder = 1;

        foreach ($data as $k => $v) {
            if ($norder < $old_order && $v['norder'] >= $norder && $v['norder'] <= $old_order)
                parent::update(array('norder' => ($v['norder'] + 1)), 'id = ' . $v['id']);

            if ($norder > $old_order && $v['norder'] >= $old_order && $v['norder'] <= $norder)
                parent::update(array('norder' => ($k)), 'id = ' . $v['id']);

            if ($v['id'] == $id)
                parent::update(array('norder' => $norder), 'id = ' . $v['id']);
        }
    }

    public function Reorder($params = array()) {
        $sel = $this->getAdapter()->select()
                ->from($this->_name)
                ->where('is_ghost = 0')
                ->where('is_removed = 0')
                ->order('norder');

        if (count($params) > 0)
            foreach ($params as $k => $v) {
                switch ($k) {
                    default:
                        if (intval($v) > 0)
                            $sel->where($this->_name . '.' . $k . ' = ?', $v);
                }
            }

        $data = $this->getList($sel)->toArray();

        foreach ($data as $k => $v) {
            parent::update(array('norder' => $k + 1), 'id = ' . $v['id']);
        }
    }

    protected function KOATUUOffsetMask($koatuu) {
        if (is_string($koatuu)) {
            $koatuu = str_pad($koatuu, 10, "0", STR_PAD_RIGHT);
            preg_match("/[0]*$/u", $koatuu, $matches, PREG_OFFSET_CAPTURE);
            $index = $matches[0][1];

            switch ($index) {
                case 1:
                case 2:
                    $index = 2;
                    break;
                case 3:
                case 4:
                case 5:
                    $index = 5;
                    break;
                case 6:
                case 7:
                case 8:
                    $index = 8;
                    break;
                case 9:
                case 10:
                    $index = 10;
                    break;
                default:
                    $index = 0;
            }

            return $index;
        } else {
            return 0;
        }
    }
    
    protected function generateRegNum($table, $column){
    	$sql = "BEGIN :regNum := GET_REGDOCNUM(".Zend_Registry::get('auth')->getIdentity()->koatuu.",'".$table."','".$column."'); end;";
        $regNum = 0;  
		$statement = $this->getAdapter()->prepare($sql);
		$statement->bindParam(':regNum', $regNum, PDO::PARAM_INT,13);
		$result = $statement->execute();
    	return $regNum;
    }
}